package com.yjhh.scala

/**
  *函数可以被简单的任务是报过了一条或几条语句的代码体，
  * 1.Scala中的函数是一等公民，可以像变量一样被传递，赋值，函数可以赋值给变量，变量也可以赋值给函数，
  *
  * 补充：整个IT编程技术发展的历史，其实就是一部封装史
  * 1.Function时代：在C语言中提供了函数的概念，用函数把若干条语句封装成
  * 2.Class时代，在C++和Java等语言提供了类和对象，把数据和处理数据的逻辑进行了封装
  * 3.框架时代，把数据，代码和驱动引擎封装起来，是当今IT技术的核心
  *
  * 函数初几入门重点
  * 1.def关键字定义函数
  * 2.函数自动进行类型推断来确定函数返回值的类型，没有‘=’则表示返回类型为Unit
  * 3.函数的参数可以是函数
  * 4.如果在函数体中无法推导出函数的返回类型，则必须申明具体的类型。
  * 5.函数的参数可以又默认值，这样在调用函数的时候如果不想改变默认值的话
  *   就直接不传递该参数，会使用默认的参数。在Spark等框架中，因为框架一般都有自己默认的配置和实现，此时可以非常好的使用默认值
  * 6.函可以基于函数的参数的名称来传递参数的顺序，原因在于函数背后是类，其实参数就是类的成员，无所谓顺序
  * 7.函数中如果不确定传入参数的个数，可以使用变长参数方式
  * 8.可变参数的数据其实会被收集为Array数组，
  *
  *   */
object FunctionalPrograming {

  def main(args: Array[String]): Unit = {
    hello("Spark")
    hello(name = "Spark",age = 32)
    println(fibonacci(7))
    println("sum = "+sum(1,2,3,4,5,6,7,8,9,10))
    println("sum = "+sum(1 to 10 : _*))
  }

  def hello(name:String,age :Int = 30) = {
    println("Hello my name is "+name)
    println("Hello my age is "+age)
    age
  }

  /**
    * 斐波那契数列
    */
  def fibonacci(num:Long) : Long = {
    if(num == 0){
      0
    }else if(num == 1){
      1
    }else{
      fibonacci(num-1) + fibonacci(num -2)
    }
  }

  /**
    * 可变参数
    * @param numbers
    * @return
    */
  def sum(numbers : Int*) : Int = {
    var result = 0
    for(number <- numbers){
      result+=number
    }
    result
  }

}
